#include "my_epd_wifi.h"

#include "pico/cyw43_arch.h"
#include "pico/stdlib.h"
#include "lwip/pbuf.h"
#include "lwip/tcp.h"

//插电后它自动联网显示天气，然后进去电子书后再出来，天气不再显示了
//对，可以改成半夜12点自动更新一次

//#define WIFI_SSID "Xiaomi_4454"
//#define WIFI_PASSWORD "123456789"
//#define WEATHER_API_URL "api.openweathermap.org"
//#define WEATHER_API_KEY "Scfxxxxxxxr8ar"
//#define CITY_ID "1816670"  // 例如北京是"1816670"

/*
抢答一下，希望大佬们有更好答案

要求基础预报功能和接口稳定性，估计中央气象台那种就行（网页抓包看数据json格式）

API的话，用和风天气的比较多
缺点是要注册ID，而且接口有调整风险。数据包是gzip格式，要解码

聚合天气 openweather
//===============================================================================
晴       Sunny   Clear   Fair
多云   Cloudy
晴间多云   Partly Cloudy
大部多云   Mostly Cloudy
阴       Overcast
阵雨    Shower
雷阵雨  Thundershower
雷阵雨伴有冰雹   Thundershower with Hail
小雨  Light Rain
中雨  Moderate Rain
大雨   Heavy Rain	
暴雨   Storm
大暴雨  Heavy Storm
特大暴雨  Severe Storm
冻雨   Ice Rain
雨夹雪  Sleet
阵雪   Snow Flurry
小雪   Light Snow
中雪   Moderate Snow
大雪   Heavy Snow
暴雪   Snowstorm
浮尘   Dust
扬沙   Sand
沙尘暴  Duststorm
强沙尘暴  Sandstorm
雾   Foggy
霾   Haze
风   Windy
大风  Blustery
飓风  Hurricane
热带风暴  Tropical Storm
龙卷风  Tornado
冷  Cold
热   Hot
未知  Unknown

● 第一优先级：冰雹、雷暴、冰粒、冰针、龙卷风、热带风暴
● 第二优先级：雪
● 第三优先级：雨
● 第四优先级：风和沙尘类（浮尘、扬沙、沙尘暴、风、大风、飓风）
● 第五优先级：雾霾
● 第六优先级：其他天气现象
心知天气更好
https://www.seniverse.com/pricing
https://www.seniverse.com/products?iid=510ab381-e5df-4482-951e-7e87fd58b799

your_private_key  Scfxxxxxxxxx8Xr8ar
https://api.seniverse.com/v3/weather/now.json?key=Scfx48lxxxxxxxxxxxar&location=beijing&language=zh-Hans&unit=c

https://api.seniverse.com/v3/weather/now.json?key=SrwLMaxxxxA2Q-7b4M&location=zhanjiang&language=zh-Hans&unit=c
//===============================================================================
gaode
https://lbs.amap.com/api/webservice/guide/api/weatherinfo

*/

#include "pico/cyw43_arch.h"
#include "pico/stdlib.h"
#include "lwip/pbuf.h"
#include "lwip/tcp.h"
#include "lwip/dns.h"

#include "read_boy_confg.h"
#include "read_boy.h"


 
#include "read_boy_base.h"
#include "read_boy_confg.h"
#include "read_boy.h"
#include "read_boy_book.h"
#include "read_boy_date_time.h"
#include "RX8025T.h"

//#define WIFI_SSID "readboy"  //"Xiaomi_4454"
//#define WIFI_PASSWORD "98765321"//"123456789"
//#define WIFI_SSID "Xiaomi_4454"
//#define WIFI_PASSWORD "123456789"//"123456789"

#define WIFI_SSID "HONOR Play5"
#define WIFI_PASSWORD "12345678"//"123456789"

#define SENIVERSE_API_HOST "api.seniverse.com"
#define SENIVERSE_API_KEY "SrwLMaxxxxxx-7b4M"
#define LOCATION "zhanjiang"  // 例如"北京"或"beijing"

static volatile bool request_complete = false;
static char weather_data[2048];
static int weather_data_len = 0;
static err_t tcp_client_connected(void *arg, struct tcp_pcb *tpcb, err_t err);
#define TIANQI_X  300
// DNS解析回调
static void dns_callback(const char *name, const ip_addr_t *ipaddr, void *arg) {
    if (ipaddr) {
        //printf("DNS resolved: %s -> %s\n", name, ipaddr_ntoa(ipaddr));
        struct tcp_pcb *pcb = (struct tcp_pcb *)arg;
        tcp_connect(pcb, ipaddr, 80, tcp_client_connected);
    } else {
        //printf("DNS resolution failed\n");
        request_complete = true;
    }
}

//void show_data2(char *weather_data){
//    int num = 0;
//    for(int i = 0; i < 25; i++){
//        for(int j = 0 ; j < 33; j++){
//            read_boy_draw_char_en(0+ j*6,i*8,read_boy_FONT_6x8,weather_data[num],0x00);
//            num++;
//            if(0 == weather_data[num]){
//                my_drv_base.drv_dispWriter(&read_boy_fb_read_one_byte,my_drv_base._quality);
//                return;
//            }
//        }
//    
//    }
//    
//    
//    
//    
//}


#include <stdio.h>
#include <stdlib.h>

char my_tq[30];
char my_code[4];
char my_temperature[10];
char my_time[30];
char Received_weather_data_flag = 0;

void str_copy_tq(char *tq,char * mystr){
    char *str;
    char num;
    str = strstr(tq,"\"");
    num = str - tq;
    strncpy(mystr,tq,num);
    mystr[num] = 0;
}
void utf_8_to_gbk_str(unsigned char *str);

void draw_tianqi_icon(uint16_t iX,uint16_t iY,uint16_t width,uint16_t hight,const uint8_t *str){
    for(int i = 0; i < hight; i++){
        for(int j = 0; j < width; j++){
            if(str[i * width + j ] != 0){
                read_boy_fb_set_one_pixel( iX+j, iY+i,0x00);
            }else{
                read_boy_fb_set_one_pixel( iX+j, iY+i,0xff);
            }
        }
    }

}

void draw_wifi_tianqi(){
    
    if(Received_weather_data_flag == 1){
        draw_tianqi_icon(TIANQI_X,10+30*4,my_tianqi_icon[my_code[0]].width,my_tianqi_icon[my_code[0]].hight,my_tianqi_icon[my_code[0]].str);
        draw_string_for_sd_start(); 
        draw_string_for_sd(TIANQI_X,10+30*4 + my_tianqi_icon[my_code[0]].hight +6, 24,my_tq);
        draw_string_for_sd_end();
        read_boy_draw_str_en(TIANQI_X,10+30*6+ my_tianqi_icon[my_code[0]].hight +6,read_boy_FONT_16x24,my_temperature,0);
        read_boy_draw_str_en(TIANQI_X,10+30*7+ my_tianqi_icon[my_code[0]].hight +6,read_boy_FONT_16x24,my_time,0);
    }
}


void show_data(char *weather_data){
    char *text ;
    char *code ;
    char *temperature;
    char *time;
    text = strstr(weather_data,"text");
    if(text != NULL){
        //Received_weather_data_flag = 1;
        text += 7;
        str_copy_tq(text,my_tq);
        utf_8_to_gbk_str(my_tq);
       
    }
    
    code = strstr(text,"code");
    if(code != NULL){
        Received_weather_data_flag = 1;
        code += 7;
        str_copy_tq(code,my_code);
        
        my_code[0] = atoi(my_code);
    }
    
    temperature = strstr(code,"temperature");
    if(temperature != NULL){
        temperature += 14;
        str_copy_tq(temperature,my_temperature);
        
    }
    
    time = strstr(temperature,"last_update");
    if(time != NULL){
        time+=14;
        str_copy_tq(time,my_time);
        
    }
    
    draw_wifi_tianqi();
    READ_BOY_BOOK_DISP;
    
    //my_drv_base.drv_dispWriter(&read_boy_fb_read_one_byte,my_drv_base._quality);    
}

// TCP接收回调
static err_t tcp_client_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
    if (!p) {
        request_complete = true;
        return ERR_OK;
    }

    if (p->tot_len > 0) {
        weather_data_len = p->tot_len < sizeof(weather_data) - 1 ? p->tot_len : sizeof(weather_data) - 1;
        pbuf_copy_partial(p, weather_data, weather_data_len, 0);
        weather_data[weather_data_len] = '\0';
        
        //printf("Received weather data:\n%s\n", weather_data);
        //=======================================
        //read_boy_fb_clear();
        show_data(weather_data);
        
        //===========================================
        tcp_recved(tpcb, p->tot_len);
    }
    
    pbuf_free(p);
    return ERR_OK;
}

// TCP连接成功回调
static err_t tcp_client_connected(void *arg, struct tcp_pcb *tpcb, err_t err) {
    if (err != ERR_OK) {
        //printf("Connect failed\n");
        request_complete = true;
        return err;
    }

    //printf("Connected to Seniverse API server\n");
    
    tcp_recv(tpcb, tcp_client_recv);
    
    // 构造心知天气API请求
    // 这里使用v3版本API，获取实时天气
    char request[256];
    snprintf(request, sizeof(request),
             "GET /v3/weather/now.json?key=%s&location=%s&language=zh-Hans&unit=c HTTP/1.1\r\n"
             "Host: %s\r\n"
             "Connection: close\r\n"
             "\r\n",
             SENIVERSE_API_KEY, LOCATION, SENIVERSE_API_HOST);
    
    err = tcp_write(tpcb, request, strlen(request), TCP_WRITE_FLAG_COPY);
    if (err != ERR_OK) {
        //printf("Failed to write request\n");
        request_complete = true;
        return err;
    }
    
    tcp_output(tpcb);
    return ERR_OK;
}

// TCP错误回调
static void tcp_client_err(void *arg, err_t err) {
    //printf("TCP client error: %d\n", err);
    request_complete = true;
}

// 开启TCP客户端连接
static bool tcp_client_open(void) {
    struct tcp_pcb *pcb = tcp_new_ip_type(IPADDR_TYPE_ANY);
    if (!pcb) {
        //printf("Failed to create PCB\n");
        return false;
    }
    
    tcp_arg(pcb, NULL);
    tcp_err(pcb, tcp_client_err);
    
    // 解析DNS
    ip_addr_t server_ip;
    err_t err = dns_gethostbyname(SENIVERSE_API_HOST, &server_ip, dns_callback, pcb);
    
    if (err == ERR_OK) {
        // 如果DNS缓存中已有记录，直接连接
        tcp_connect(pcb, &server_ip, 80, tcp_client_connected);
    } else if (err != ERR_INPROGRESS) {
        //printf("DNS lookup failed\n");
        return false;
    }
    
    return true;
}

int xinzhi_tianqi_main() {
    //stdio_init_all();
    
    // 初始化WiFi
    if (cyw43_arch_init()) {
        //printf("Failed to initialize WiFi\n");
        return -1;
    }
    
    cyw43_arch_enable_sta_mode();
    
    //printf("Connecting to WiFi...\n");
    //read_boy_fb_clear();
    read_boy_draw_str_en(TIANQI_X,10,read_boy_FONT_6x8,"Connecting to WiFi",0);
    READ_BOY_BOOK_DISP;
    //my_drv_base.drv_dispWriter(&read_boy_fb_read_one_byte,my_drv_base._quality);
    
    if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 30000)) {
        //printf("Failed to connect to WiFi\n");
        read_boy_draw_str_en(TIANQI_X,10+30*1,read_boy_FONT_6x8,"Failed to connect to WiFi",0);
        //my_drv_base.drv_dispWriter(&read_boy_fb_read_one_byte,my_drv_base._quality);
        cyw43_arch_deinit();
        return -1;
    }
    read_boy_draw_str_en(TIANQI_X,10+30*1,read_boy_FONT_6x8,"WiFi connected",0);
    
    read_boy_draw_str_en(TIANQI_X,10+30*2,read_boy_FONT_6x8,"start weather request",0);
    READ_BOY_BOOK_DISP;
    //my_drv_base.drv_dispWriter(&read_boy_fb_read_one_byte,my_drv_base._quality);
    
    //printf("WiFi connected\n");
    //printf("IP: %s\n", ip4addr_ntoa(netif_ip4_addr(netif_list)));
    //for(int i = 0; i < 2; i++){
        // 获取天气数据
        if (!tcp_client_open()) {
            //printf("Failed to start weather request\n");
            read_boy_draw_str_en(TIANQI_X,10+30*3,read_boy_FONT_6x8,"sFailed to start weather request",0);
            //my_drv_base.drv_dispWriter(&read_boy_fb_read_one_byte,my_drv_base._quality);
            cyw43_arch_deinit();
            return -1;
        }
        
        // 等待请求完成
        while (!request_complete) {
            cyw43_arch_poll();
            sleep_ms(100);
        }
        
        //sleep_ms(20000);
        
    //}
    
    // 这里可以添加JSON解析代码处理weather_data中的响应
    
    //cyw43_arch_deinit();
    return 0;
}

uint16_t utf8_to_gbk(uint8_t x1,uint8_t x2,uint8_t x3);
void utf_8_to_gbk_str(unsigned char *str){
    int num = 0;
    int gbk_num = 0;
    uint16_t data_temp;
    //char data[100];
    unsigned char *pt = str;
    while( pt[num]){
        if(pt[num] <= 0x7f){
            pt[gbk_num] = pt[num];
            num++;
            gbk_num++;
        }else{
            if(pt[num] <= 0xD1){
                pt[gbk_num] = '-';
                pt[gbk_num + 1] = '-';
                num+=2;
                gbk_num+=2;
            }else{
                data_temp = utf8_to_gbk(pt[num],pt[num+1],pt[num+2]); 
                if(data_temp == 0){
                    pt[gbk_num] = '.';
                    pt[gbk_num + 1] = '.';
                }else{
                    pt[gbk_num] = data_temp / 256;
                    pt[gbk_num + 1] = data_temp % 256;
                }
                num+=3;
                gbk_num+=2;
            }
        }
    }
    pt[gbk_num] = 0;
    
}


//=====================================
extern const uint8_t c_bmptianqix00Alpha[48*48];
extern const uint8_t c_bmptianqix01Alpha[48*48];
extern const uint8_t c_bmptianqix02Alpha[48*48];
extern const uint8_t c_bmptianqix03Alpha[48*48];
extern const uint8_t c_bmptianqix04Alpha[58*38];

extern const uint8_t c_bmptianqix05Alpha[58*41];
extern const uint8_t c_bmptianqix06Alpha[58*48];
extern const uint8_t c_bmptianqix07Alpha[58*41];
extern const uint8_t c_bmptianqix08Alpha[58*48];
extern const uint8_t c_bmptianqix09Alpha[58*38] ;

extern const uint8_t c_bmptianqix10Alpha[58*57];
extern const uint8_t c_bmptianqix11Alpha[58*58];
extern const uint8_t c_bmptianqix12Alpha[58*58];
extern const uint8_t c_bmptianqix13Alpha[58*57];
extern const uint8_t c_bmptianqix14Alpha[58*57];

extern const uint8_t c_bmptianqix15Alpha[58*58];
extern const uint8_t c_bmptianqix16Alpha[58*58];
extern const uint8_t c_bmptianqix17Alpha[61*61];
extern const uint8_t c_bmptianqix18Alpha[61*61];
extern const uint8_t c_bmptianqix19Alpha[58*58];

extern const uint8_t c_bmptianqix20Alpha[58*57];
extern const uint8_t c_bmptianqix21Alpha[58*58];
extern const uint8_t c_bmptianqix22Alpha[58*55];
extern const uint8_t c_bmptianqix23Alpha[58*55];
extern const uint8_t c_bmptianqix24Alpha[58*55];

extern const uint8_t c_bmptianqix25Alpha[58*58];
extern const uint8_t c_bmptianqix26Alpha[58*49];
extern const uint8_t c_bmptianqix27Alpha[58*49];
extern const uint8_t c_bmptianqix28Alpha[58*34];
extern const uint8_t c_bmptianqix29Alpha[58*34];

extern const uint8_t c_bmptianqix30Alpha[56*51];
extern const uint8_t c_bmptianqix31Alpha[58*51];
extern const uint8_t c_bmptianqix32Alpha[58*46];
extern const uint8_t c_bmptianqix33Alpha[58*46];
extern const uint8_t c_bmptianqix34Alpha[58*58];

extern const uint8_t c_bmptianqix35Alpha[58*58];//
extern const uint8_t c_bmptianqix36Alpha[58*57];
extern const uint8_t c_bmptianqix37Alpha[50*58];
extern const uint8_t c_bmptianqix38Alpha[48*48];
extern const uint8_t c_bmptianqix39Alpha[58*25];

const tianqi_icon_t my_tianqi_icon[40]={
    {.width = 48,.hight = 48,.str = c_bmptianqix00Alpha},
    {.width = 48,.hight = 48,.str = c_bmptianqix01Alpha},
    {.width = 48,.hight = 48,.str = c_bmptianqix02Alpha},
    {.width = 48,.hight = 48,.str = c_bmptianqix03Alpha},
    {.width = 58,.hight = 38,.str = c_bmptianqix04Alpha},
    
    {.width = 58,.hight = 41,.str = c_bmptianqix05Alpha},
    {.width = 58,.hight = 48,.str = c_bmptianqix06Alpha},
    {.width = 58,.hight = 41,.str = c_bmptianqix07Alpha},
    {.width = 58,.hight = 48,.str = c_bmptianqix08Alpha},
    {.width = 58,.hight = 38,.str = c_bmptianqix09Alpha},
    
    {.width = 58,.hight = 57,.str = c_bmptianqix10Alpha},
    {.width = 58,.hight = 58,.str = c_bmptianqix11Alpha},
    {.width = 58,.hight = 58,.str = c_bmptianqix12Alpha},
    {.width = 58,.hight = 57,.str = c_bmptianqix13Alpha},
    {.width = 58,.hight = 57,.str = c_bmptianqix14Alpha},
    
    {.width = 58,.hight = 58,.str = c_bmptianqix15Alpha},
    {.width = 58,.hight = 58,.str = c_bmptianqix16Alpha},
    {.width = 61,.hight = 61,.str = c_bmptianqix17Alpha},
    {.width = 61,.hight = 61,.str = c_bmptianqix18Alpha},
    {.width = 58,.hight = 58,.str = c_bmptianqix19Alpha},
    
    {.width = 58,.hight = 57,.str = c_bmptianqix20Alpha},
    {.width = 58,.hight = 58,.str = c_bmptianqix21Alpha},
    {.width = 58,.hight = 55,.str = c_bmptianqix22Alpha},
    {.width = 58,.hight = 55,.str = c_bmptianqix23Alpha},
    {.width = 58,.hight = 55,.str = c_bmptianqix24Alpha},
    
    {.width = 58,.hight = 58,.str = c_bmptianqix25Alpha},
    {.width = 58,.hight = 49,.str = c_bmptianqix26Alpha},
    {.width = 58,.hight = 49,.str = c_bmptianqix27Alpha},
    {.width = 58,.hight = 34,.str = c_bmptianqix28Alpha},
    {.width = 58,.hight = 34,.str = c_bmptianqix29Alpha},
    
    {.width = 56,.hight = 51,.str = c_bmptianqix30Alpha},
    {.width = 58,.hight = 51,.str = c_bmptianqix31Alpha},
    {.width = 58,.hight = 46,.str = c_bmptianqix32Alpha},
    {.width = 58,.hight = 46,.str = c_bmptianqix33Alpha},
    {.width = 58,.hight = 58,.str = c_bmptianqix34Alpha},
    
    {.width = 58,.hight = 58,.str = c_bmptianqix35Alpha},//
    {.width = 58,.hight = 57,.str = c_bmptianqix36Alpha},
    {.width = 50,.hight = 58,.str = c_bmptianqix37Alpha},
    {.width = 48,.hight = 48,.str = c_bmptianqix38Alpha},
    {.width = 58,.hight = 25,.str = c_bmptianqix39Alpha},
};

//static volatile bool request_complete = false;
//static char weather_data[2048];
//static int weather_data_len = 0;

//static err_t tcp_client_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
//    if (!p) {
//        request_complete = true;
//        return ERR_OK;
//    }

//    if (p->tot_len > 0) {
//        weather_data_len = p->tot_len < sizeof(weather_data) - 1 ? p->tot_len : sizeof(weather_data) - 1;
//        pbuf_copy_partial(p, weather_data, weather_data_len, 0);
//        weather_data[weather_data_len] = '\0';
//        
//        printf("Received weather data:\n%s\n", weather_data);
//        
//        tcp_recved(tpcb, p->tot_len);
//    }
//    
//    pbuf_free(p);
//    return ERR_OK;
//}

//static err_t tcp_client_connected(void *arg, struct tcp_pcb *tpcb, err_t err) {
//    if (err != ERR_OK) {
//        printf("Connect failed\n");
//        return err;
//    }

//    printf("Connected to weather server\n");
//    
//    // 设置接收回调
//    tcp_recv(tpcb, tcp_client_recv);
//    
//    // 构造HTTP GET请求
//    char request[256];
//    snprintf(request, sizeof(request),
//             "GET /data/2.5/weather?id=%s&appid=%s&units=metric HTTP/1.1\r\n"
//             "Host: %s\r\n"
//             "Connection: close\r\n"
//             "\r\n",
//             CITY_ID, WEATHER_API_KEY, WEATHER_API_URL);
//    
//    // 发送请求
//    err = tcp_write(tpcb, request, strlen(request), TCP_WRITE_FLAG_COPY);
//    if (err != ERR_OK) {
//        printf("Failed to write request\n");
//        return err;
//    }
//    
//    tcp_output(tpcb);
//    return ERR_OK;
//}

//static void tcp_client_err(void *arg, err_t err) {
//    printf("TCP client error: %d\n", err);
//    request_complete = true;
//}

//static bool tcp_client_open(void) {
//    struct tcp_pcb *pcb = tcp_new_ip_type(IPADDR_TYPE_ANY);
//    if (!pcb) {
//        printf("Failed to create PCB\n");
//        return false;
//    }
//    
//    ip_addr_t server_ip;
//    if (!ipaddr_aton(WEATHER_API_URL, &server_ip)) {
//        printf("DNS lookup will be needed\n");
//        // 实际应用中这里应该添加DNS查询代码
//        return false;
//    }
//    
//    tcp_arg(pcb, NULL);
//    tcp_err(pcb, tcp_client_err);
//    
//    // 连接到服务器(HTTP端口80)
//    err_t err = tcp_connect(pcb, &server_ip, 80, tcp_client_connected);
//    if (err != ERR_OK) {
//        printf("Failed to connect\n");
//        return false;
//    }
//    
//    return true;
//}

//int wifi_main() {
//    stdio_init_all();
//    
//    // 初始化WiFi
//    if (cyw43_arch_init()) {
//        printf("Failed to initialize WiFi\n");
//        return -1;
//    }
//    
//    cyw43_arch_enable_sta_mode();
//    
//    printf("Connecting to WiFi...\n");
//    if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 30000)) {
//        printf("Failed to connect to WiFi\n");
//        return -1;
//    }
//    
//    printf("WiFi connected\n");
//    printf("IP: %s\n", ip4addr_ntoa(netif_ip4_addr(netif_list)));
//    
//    // 获取天气数据
//    if (!tcp_client_open()) {
//        printf("Failed to start weather request\n");
//        cyw43_arch_deinit();
//        return -1;
//    }
//    
//    // 等待请求完成
//    while (!request_complete) {
//        cyw43_arch_poll();
//        sleep_ms(100);
//    }
//    
//    // 解析天气数据 (这里可以添加JSON解析代码)
//    
//    cyw43_arch_deinit();
//    return 0;
//}

























